<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>js中的闭包</title>
		<script type="text/javascript">			
			
			// 函数中可以定义函数
			function f1(){
				var age = 10;  // age 属于 f1函数的作用域
				function f2(){
					var age = 100; // age属于f2函数的作用域
					console.info("age-inner："+age);
				}
				// 调用内层函数
				f2();
				console.info("age-outer："+age)
			}
			
			// 调用外层函数
			f1();
			
			// 函数可以作为参数进行传递
			function ff1(ff2){
				var age = 10;
				ff2(age);
			}
			// 使用匿名函数作为实参传递给形参
			ff1(
				function(a){
					a+=2;
					console.info("a："+a);
				}
			);
			
			
			
			// 实现一个计数器的功能，每调用一次函数计数器变量+1，且要求除了该函数之外，不能有其他途径改变该计数器
			// 函数嵌套
			
			function  fff1(){
				// fff1函数作用域的变量
				var count = 0;
				function fff2(){
					// 访问函数外部的变量
					count++;
					// 输出变量
					console.info("count："+count);
				}
				// 调用fff2函数
				fff2();
			}
			
			// 调用一下外层函数，进而执行内层函数
			fff1();
			fff1();
			
			console.info("=========================")
			
			// 使用闭包完成上述业务需求
			function  ffff1(){
				// ffff1函数作用域的变量
				var count = 0;
				// 将函数ffff2作为return的返回值进行返回
				return function ffff2(){
					// ffff2的作用域
					// 访问函数外部的变量
					count++;
					// 输出变量
					console.info("count："+count);
				};				
			}
			
			// 创建一个变量接收函数ffff1的返回值【返回值是一个函数】
			/*
			 * 在执行ffff1();语句时会在内存中创建该函数的作用域ffff1，该函数的作用域中包含变量count
			 * 在 var counter = ffff1();语句执行完成之后，按照释放内存的原则应该释放掉作用域ffff1,
			 * 但是在执行counter();语句时，因为counter指向的是内层函数ffff2，需要在内存中创建作用域ffff2，
			 * 且作用域ffff2是作用ffff1的子作用域，并且ffff2中引用了作用域ffff1中的变量count，这样就造成了
			 * 虽然var counter = ffff1();虽然执行完成，但作用域ffff1不释放的情况，所以作用域ffff1不能释放
			 * 直到所有的作用域ffff2结束为止，作用域ffff1一直常驻内存，且只能通过作用域ffff2才能访问；
			 * 
			 * 这样形成一种结果：ffff2作用域中的变量count类似于java中的静态变量，常驻内存；【这种情况和java静态变量不同】
			 */
			var counter = ffff1(); // counter其实就是ffff1中的内层函数ffff2
			counter(); // 创建作用域ffff2
			counter(); //作用域ffff2
		</script>
	</head>
	<body>
	</body>
</html>
